//
// Created by LiuYou on 2021/10/22.
//

#include <iostream>
#include <unistd.h>
#include <csignal>

// todo 笔记: volatile: 去这个变量/对象的真正空间去取这个变量的值, 不要...。
//  加上 volatile, 这个程序就可以通过 gcc 做优化了。

/*
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$ g++ Signal-5sec-signal.cpp -O1
// 这个程序是不会停止的！！！
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$ ./a.out
^C
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$
 */

/*
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$ g++ Signal-5sec-signal.cpp -O1
// 加上 volatile 程序才会成功运行。
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$ time ./a.out > /tmp/out

real    0m5.032s
user    0m4.955s
sys     0m0.028s
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$ cat /tmp/out
15666122059
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$

// 使用gcc优化后, 程序执行为:
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$ time ./a.out > /tmp/out

real    0m5.032s
user    0m4.955s
sys     0m0.028s
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$ cat /tmp/out
15666122059
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$

// 之前使用 time(); 是
2384268828
// 使用 没有优化的 alarm(); 是
2729797572
// 使用 gcc优化的 alarm(); 是
15666122059
 */

static volatile bool isLoop{true};

/*
    volatile作用:

    * 状态寄存器一类的并行设备硬件寄存器。

    * 一个中断服务子程序会访问到的非自动变量。

    * 多线程间被几个任务共享的变量。

    注意: 虽然volatile在嵌入式方面应用比较多，但是在PC软件的多线程中，
    volatile修饰的临界变量也是非常实用的。
*/



static void alarmHandler(int sig) {
    isLoop = false;
}


/*
 * 有了 alarm();之后程序就有了时间观念, 有了时间观念就可以干很多和时间相关的事情。
 */


int main(int argc, char** argv) {
    //<editor-fold desc="使用time();来控制时间。">
//    int64_t count = 0;
//    time_t end = time( nullptr ) + 5;
//    while (time( nullptr ) <= end) {
//        ++count;
//    }
//    printf( "%ld\n", count );
    //</editor-fold>

    int64_t count{};

    // todo 笔记: alarm();和signal();一定有顺序要求！
    //  一定一定一定把 信号处理函数 写在 alarm(); 发出信号之前。
    signal( SIGALRM, alarmHandler );
    alarm( 5 );

    while (isLoop) {
        ++count;
    }

    printf( "%ld\n", count );

    return 0;
}

/*
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$ ./a.out
2194535942
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$ time ./a.out > /tmp/out1

real    0m5.010s
user    0m4.945s
sys     0m0.029s
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$ time ./a.out > /tmp/out1

real    0m5.030s
user    0m4.994s
sys     0m0.005s
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$ time ./a.out > /tmp/out1

real    0m5.029s
user    0m4.929s
sys     0m0.028s
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$
// todo 笔记: 相较于time();而言, 时间精度提升了很多。

liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$ cat /tmp/out
2384268828
// todo 笔记: time();是系统调用, 每次执行time();都会取时间戳, 它要扎内核取时戳。所以不如
// todo 笔记: alarm();更加准确。
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$ cat /tmp/out1
2729797572
liuyou@liuyou-virtual-machine:~/CLionProjects/LinuxEnvironmentProgramming2/src/concurrence/parallel/signal$


 */